﻿using System.Collections;
using System.ComponentModel;
using System.Security.Permissions;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml.Serialization;

namespace Halcyonetic.Web.UI
{
    [AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal), AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
    public class HSRSS : DataBoundControl
    {
        #region Properties

        private string _DataTitle = string.Empty;

        private string _DataLink = string.Empty;

        private string _DataDescription = string.Empty;

        private string _DataAuthor = string.Empty;

        private string _DataCategory = string.Empty;

        private string _DataComments = string.Empty;

        private string _DataEnclosure = string.Empty;

        private string _DataGuid = string.Empty;

        private string _DataPubDate = string.Empty;

        private string _Data_Source = string.Empty;

        /// <remarks/>
        [Bindable(true), Category("Data"), DefaultValue(""), Localizable(true)]
        public string DataTitle
        {
            get
            {
                return this._DataTitle;
            }
            set
            {
                this._DataTitle = value;
            }
        }

        /// <remarks/>
        [Bindable(true), Category("Data"), DefaultValue(""), Localizable(true)]
        public string DataLink
        {
            get
            {
                return this._DataLink;
            }
            set
            {
                this._DataLink = value;
            }
        }

        /// <remarks/>
        [Bindable(true), Category("Data"), DefaultValue(""), Localizable(true)]
        public string DataDescription
        {
            get
            {
                return this._DataDescription;
            }
            set
            {
                this._DataDescription = value;
            }
        }

        /// <remarks/>
        [Bindable(true), Category("Data"), DefaultValue(""), Localizable(true)]
        public string DataAuthor
        {
            get
            {
                return this._DataAuthor;
            }
            set
            {
                this._DataAuthor = value;
            }
        }

        /// <remarks/>
        [Bindable(true), Category("Data"), DefaultValue(""), Localizable(true)]
        public string DataCategory
        {
            get
            {
                return this._DataCategory;
            }
            set
            {
                this._DataCategory = value;
            }
        }

        /// <remarks/>
        [Bindable(true), Category("Data"), DefaultValue(""), Localizable(true)]
        public string DataComments
        {
            get
            {
                return this._DataComments;
            }
            set
            {
                this._DataComments = value;
            }
        }

        /// <remarks/>
        [Bindable(true), Category("Data"), DefaultValue(""), Localizable(true)]
        public string DataEnclosure
        {
            get
            {
                return this._DataEnclosure;
            }
            set
            {
                this._DataEnclosure = value;
            }
        }

        /// <remarks/>
        [Bindable(true), Category("Data"), DefaultValue(""), Localizable(true)]
        public string DataGuid
        {
            get
            {
                return this._DataGuid;
            }
            set
            {
                this._DataGuid = value;
            }
        }

        /// <remarks/>
        [Bindable(true), Category("Data"), DefaultValue(""), Localizable(true)]
        public string DataPubDate
        {
            get
            {
                return this._DataPubDate;
            }
            set
            {
                this._DataPubDate = value;
            }
        }


        /// <remarks/>
        [Bindable(true), Category("Data"), DefaultValue(""), Localizable(true)]
        public string Data_Source
        {
            get
            {
                return this._Data_Source;
            }
            set
            {
                this._Data_Source = value;
            }
        }


        //private string _Description = string.Empty;
        //[Bindable(true), Category("Data"), DefaultValue("description"), Localizable(true)]
        //public string DescriptionField
        //{
        //    get
        //    {
        //        return _Description.ToLower();
        //    }
        //    set
        //    {
        //        _Description = value;
        //    }
        //}

        //private string _ChannelIdField = string.Empty;
        //[Bindable(true), Category("Data"), DefaultValue("channel_Id"), Localizable(true)]
        //public string ChannelIdField
        //{
        //    get
        //    {
        //        return _ChannelIdField.ToLower();
        //    }
        //    set
        //    {
        //        _ChannelIdField = value;
        //    }
        //}

        //private string _ItemLinkField = string.Empty;
        //[Bindable(true), Category("Data"), DefaultValue("link"), Localizable(true)]
        //public string ItemLinkField
        //{
        //    get
        //    {
        //        return _ItemLinkField.ToLower();
        //    }
        //    set
        //    {
        //        _ItemLinkField = value;
        //    }
        //}

        //private string _PubDateField = string.Empty;
        //[Bindable(true), Category("Data"), DefaultValue("pubDate"), Localizable(true)]
        //public string PubDateField
        //{
        //    get
        //    {
        //        return _PubDateField.ToLower();
        //    }
        //    set
        //    {
        //        _PubDateField = value;
        //    }
        //}

        //private string _TitleField = string.Empty;
        //[Bindable(true), Category("Data"), Localizable(true)]
        //public string TitleField
        //{
        //    get
        //    {
        //        return _TitleField.ToLower();
        //    }
        //    set
        //    {
        //        _TitleField = value;
        //    }
        //}

        //private string _CategoryField = string.Empty;
        //[Bindable(true), Category("Data"), DefaultValue("CategoryField"), Localizable(true)]
        //public string CategoryField
        //{
        //    get
        //    {
        //        return _CategoryField.ToLower();
        //    }
        //    set
        //    {
        //        _CategoryField = value;
        //    }
        //}

        //TODO:  Add GeoRSS support

        private string titleField;

        private string linkField;

        private string descriptionField;

        private string languageField;

        private string copyrightField;

        private string lastBuildDateField;

        private string docsField;

        private string managingEditorField;

        private string webMasterField;

        private string ttlField;

        /// <remarks/>
        [Bindable(true), Category("RSS Settings"), DefaultValue(""), Localizable(true)]
        public string title
        {
            get
            {
                return this.titleField;
            }
            set
            {
                this.titleField = value;
            }
        }

        /// <remarks/>
        [Bindable(true), Category("RSS Settings"), DefaultValue(""), Localizable(true)]
        public string link
        {
            get
            {
                return this.linkField;
            }
            set
            {
                this.linkField = value;
            }
        }

        /// <remarks/>
        [Bindable(true), Category("RSS Settings"), DefaultValue(""), Localizable(true)]
        public string description
        {
            get
            {
                return this.descriptionField;
            }
            set
            {
                this.descriptionField = value;
            }
        }

        /// <remarks/>
        [Bindable(true), Category("RSS Settings"), DefaultValue(""), Localizable(true)]
        public string language
        {
            get
            {
                return this.languageField;
            }
            set
            {
                this.languageField = value;
            }
        }

        /// <remarks/>
        [Bindable(true), Category("RSS Settings"), DefaultValue(""), Localizable(true)]
        public string copyright
        {
            get
            {
                return this.copyrightField;
            }
            set
            {
                this.copyrightField = value;
            }
        }

        /// <remarks/>
        [Bindable(true), Category("RSS Settings"), DefaultValue(""), Localizable(true)]
        public string lastBuildDate
        {
            get
            {
                return this.lastBuildDateField;
            }
            set
            {
                this.lastBuildDateField = value;
            }
        }

        /// <remarks/>
        [Bindable(true), Category("RSS Settings"), DefaultValue(""), Localizable(true)]
        public string docs
        {
            get
            {
                return this.docsField;
            }
            set
            {
                this.docsField = value;
            }
        }

        /// <remarks/>
        [Bindable(true), Category("RSS Settings"), DefaultValue(""), Localizable(true)]
        public string managingEditor
        {
            get
            {
                return this.managingEditorField;
            }
            set
            {
                this.managingEditorField = value;
            }
        }

        /// <remarks/>
        [Bindable(true), Category("RSS Settings"), DefaultValue(""), Localizable(true)]
        public string webMaster
        {
            get
            {
                return this.webMasterField;
            }
            set
            {
                this.webMasterField = value;
            }
        }

        /// <remarks/>
        [Bindable(true), Category("RSS Settings"), DefaultValue(""), Localizable(true)]
        public string ttl
        {
            get
            {
                return this.ttlField;
            }
            set
            {
                this.ttlField = value;
            }
        }

        #endregion
        
        public string XmlOutput;

        protected override void PerformDataBinding(IEnumerable retrievedData)
        {
            base.PerformDataBinding(retrievedData);
            
            // Verify data exists.
            if (!(retrievedData == null))
            {

                //TODO:  Find a better way to count the number of items
                int Counter = 0;
                foreach (var dataItem in retrievedData)
                {
                    Counter++;
                }
                
                var rowXml = new rss {version = "2.0"};

                var channels = new rssChannel[1];
                channels[0] = new rssChannel();
                if(!string.IsNullOrEmpty(titleField))
                    channels[0].title = titleField;
                if (!string.IsNullOrEmpty(linkField))
                    channels[0].link = linkField;
                if (!string.IsNullOrEmpty(descriptionField))
                    channels[0].description = descriptionField;
                if (!string.IsNullOrEmpty(languageField))
                    channels[0].language = languageField;
                if (!string.IsNullOrEmpty(copyrightField))
                    channels[0].copyright = copyrightField;
                if (!string.IsNullOrEmpty(lastBuildDateField))
                    channels[0].lastBuildDate = lastBuildDateField;
                if (!string.IsNullOrEmpty(docsField))
                    channels[0].docs = docsField;
                channels[0].generator = "HSRSS";
                if (!string.IsNullOrEmpty(managingEditorField))
                    channels[0].managingEditor = managingEditorField;
                if (!string.IsNullOrEmpty(webMasterField))
                    channels[0].webMaster = webMasterField;
                if (!string.IsNullOrEmpty(ttlField))
                    channels[0].ttl = ttlField;

                var items = new rssChannelItem[Counter];
                

                //*sigh* reset the counter again
                Counter = 0;
                foreach (var dataItem in retrievedData)
                {
                    //retrieve all the properties
                    var props = TypeDescriptor.GetProperties(dataItem);
                    
                    //init item
                    items[Counter] = new rssChannelItem();

                    //set values
                    if (!(props[DataTitle] == null))
                        items[Counter].title = DataBinder.GetPropertyValue(dataItem, DataTitle, null);
                    if (!(props[DataLink] == null))
                        items[Counter].link = DataBinder.GetPropertyValue(dataItem, DataLink, null);
                    if (!(props[DataDescription] == null))
                        items[Counter].description = DataBinder.GetPropertyValue(dataItem, DataDescription, null);
                    if (!(props[DataAuthor] == null))
                        items[Counter].pubDate = DataBinder.GetPropertyValue(dataItem, DataAuthor, null);
                    if (!(props[DataDescription] == null))
                        items[Counter].description = DataBinder.GetPropertyValue(dataItem, DataDescription, null);
                    if (!(props[DataGuid] == null))
                        items[Counter].guid = DataBinder.GetPropertyValue(dataItem, DataGuid, null);
                    if (!(props[DataLink] == null))
                        items[Counter].link = DataBinder.GetPropertyValue(dataItem, DataLink, null);
                    if (!(props[DataPubDate] == null))
                        items[Counter].pubDate = DataBinder.GetPropertyValue(dataItem, DataPubDate, null);
                    if (!(props[DataComments] == null))
                        items[Counter].comments = DataBinder.GetPropertyValue(dataItem, DataComments, null);
                    if (!(props[Data_Source] == null))
                        items[Counter].source = DataBinder.GetPropertyValue(dataItem, Data_Source, null);

                    Counter++;
                }

                //add everything together
                channels[0].item = items;
                rowXml.channel = channels;
                var ns = new XmlSerializerNamespaces();
                ns.Add("", "");
                XmlOutput = Common.Xml.Serialize.Generic(rowXml, ns);
            }
        }

        protected override void Render(HtmlTextWriter writer)
        {
            if (DesignMode)
            {
                writer.Write("RSS Generator version 1.0");
                base.Render(writer);
            }
            else
            {
                //write the output
                writer.Write(XmlOutput);
            }

        }

    }

}


//Autogenerated class for RSS xml
namespace Halcyonetic.Web.UI
{
    /// <remarks/>
    //[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
    public partial class rss
    {

        private rssChannel[] channelField;

        private string versionField;

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute("channel", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public rssChannel[] channel
        {
            get
            {
                return this.channelField;
            }
            set
            {
                this.channelField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlAttributeAttribute()]
        public string version
        {
            get
            {
                return this.versionField;
            }
            set
            {
                this.versionField = value;
            }
        }
    }

    /// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
    [System.SerializableAttribute()]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
    public partial class rssChannel
    {

        private string titleField;

        private string linkField;

        private string descriptionField;

        private string languageField;

        private string copyrightField;

        private string lastBuildDateField;

        private string docsField;

        private string generatorField;

        private string managingEditorField;

        private string webMasterField;

        private string ttlField;

        private rssChannelCategory[] categoryField;

        private rssChannelItem[] itemField;

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string title
        {
            get
            {
                return this.titleField;
            }
            set
            {
                this.titleField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string link
        {
            get
            {
                return this.linkField;
            }
            set
            {
                this.linkField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string description
        {
            get
            {
                return this.descriptionField;
            }
            set
            {
                this.descriptionField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string language
        {
            get
            {
                return this.languageField;
            }
            set
            {
                this.languageField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string copyright
        {
            get
            {
                return this.copyrightField;
            }
            set
            {
                this.copyrightField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string lastBuildDate
        {
            get
            {
                return this.lastBuildDateField;
            }
            set
            {
                this.lastBuildDateField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string docs
        {
            get
            {
                return this.docsField;
            }
            set
            {
                this.docsField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string generator
        {
            get
            {
                return this.generatorField;
            }
            set
            {
                this.generatorField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string managingEditor
        {
            get
            {
                return this.managingEditorField;
            }
            set
            {
                this.managingEditorField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string webMaster
        {
            get
            {
                return this.webMasterField;
            }
            set
            {
                this.webMasterField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string ttl
        {
            get
            {
                return this.ttlField;
            }
            set
            {
                this.ttlField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute("category", Form = System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable = true)]
        public rssChannelCategory[] category
        {
            get
            {
                return this.categoryField;
            }
            set
            {
                this.categoryField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute("item", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public rssChannelItem[] item
        {
            get
            {
                return this.itemField;
            }
            set
            {
                this.itemField = value;
            }
        }
    }

    /// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
    [System.SerializableAttribute()]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
    public partial class rssChannelCategory
    {

        private string domainField;

        private string valueField;

        /// <remarks/>
        [System.Xml.Serialization.XmlAttributeAttribute()]
        public string domain
        {
            get
            {
                return this.domainField;
            }
            set
            {
                this.domainField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlTextAttribute()]
        public string Value
        {
            get
            {
                return this.valueField;
            }
            set
            {
                this.valueField = value;
            }
        }
    }

    /// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
    [System.SerializableAttribute()]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
    public partial class rssChannelItem
    {

        private string titleField;

        private string linkField;

        private string descriptionField;

        private string authorField;

        private string categoryField;

        private string commentsField;

        private string enclosureField;

        private string guidField;

        private string pubDateField;

        private string sourceField;

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string title
        {
            get
            {
                return this.titleField;
            }
            set
            {
                this.titleField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string link
        {
            get
            {
                return this.linkField;
            }
            set
            {
                this.linkField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string description
        {
            get
            {
                return this.descriptionField;
            }
            set
            {
                this.descriptionField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string author
        {
            get
            {
                return this.authorField;
            }
            set
            {
                this.authorField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string category
        {
            get
            {
                return this.categoryField;
            }
            set
            {
                this.categoryField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string comments
        {
            get
            {
                return this.commentsField;
            }
            set
            {
                this.commentsField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string enclosure
        {
            get
            {
                return this.enclosureField;
            }
            set
            {
                this.enclosureField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string guid
        {
            get
            {
                return this.guidField;
            }
            set
            {
                this.guidField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string pubDate
        {
            get
            {
                return this.pubDateField;
            }
            set
            {
                this.pubDateField = value;
            }
        }


        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string source
        {
            get
            {
                return this.sourceField;
            }
            set
            {
                this.sourceField = value;
            }
        }

    }
}
